# coding=utf8
from apscheduler.scheduler import Scheduler
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage, InvalidPage
from rest_framework import viewsets
from rest_framework.response import Response
from django.http import JsonResponse
from user.apis import MyPageNumberPagination, CsrfExemptSessionAuthentication
from .serializers import ChatRecordSerializers, WordReplyMapSerializers
from .models import ChatRecord, WordReplyMap
from user.models import User
from django.db.models import Q
from user.views import auth
import queue

# 消息队列
record_queue = queue.Queue()


# 聊天记录
class ChatRecordViewSet(viewsets.ModelViewSet):
    serializer_class = ChatRecordSerializers
    queryset = ChatRecord.objects.all()
    authentication_classes = (CsrfExemptSessionAuthentication,)

    # 返回我自己和指定人的聊天记录
    @auth()
    def list(self, request):
        receiver_id = request.GET.get('receiver_id')
        page = int(request.GET.get('page', '1'))
        size = int(request.GET.get('size', '10'))
        is_read = bool(request.GET.get('is_read'))  # 通过is_read来判断是获取所有消息还是未读消息
        queryset = ChatRecord.objects.filter((Q(sender=request.user) & Q(
            receiver__id=receiver_id)) | (Q(sender__id=receiver_id) & Q(receiver=request.user))).filter(
            Q(is_return=False) & Q(is_read=is_read))

        paginator = Paginator(queryset, size)  # 创建分页对象，每页10条数据
        try:
            page_obj = paginator.page(page)  # 获取某一页的数据
        except (PageNotAnInteger, EmptyPage, InvalidPage):
            page_obj = paginator.page('1')  # 发生错误跳转到第一页
        serializer = ChatRecordSerializers(page_obj.object_list, many=True)
        return Response({
            'code': '200',
            'msg': '响应成功!',
            'data': serializer.data
        })

    # 新增聊天记录
    @auth()
    def create(self, request):
        receiver_id = request.POST.get('receiver_id')
        receiver = User.get_by_pk(receiver_id)
        # 判断接收者是否存在
        if not receiver:
            return JsonResponse({
                'code': '400',
                'msg': '接收者不存在!',
            })

        content = request.POST.get('content')
        new_record = ChatRecord.create_record(request.user, receiver, content)

        # 更新忙录值
        request.user.update_busy_score(-1)
        receiver.update_busy_score(1)

        # 添加到消息队列
        if (
                not new_record.is_read
                and not new_record.is_return  # 未读 且未撤回
                and (
                # 非客服开启了自动回复
                not receiver.is_staff
                and receiver.is_auto_reply
                # 客服默认开启自动回复
                or receiver.is_staff
        )
        ):
            record_queue.put(new_record.id)

        return Response(
            {'code': '200',
             'msg': '新增成功!',
             'data': {
                 'sender': {
                     'id': request.user.id,
                     'username': request.user.username,
                 },
                 'receiver': {'id': receiver.id,
                              'username': receiver.username,
                              },
                 'content': content
             },
             'time': new_record.time
             })

    # 修改聊天记录状态
    @auth()
    def update(self, request, pk=None):
        tmp_record = ChatRecord.get_by_pk(pk)
        # 判断聊天记录是否存在
        if not tmp_record:
            return JsonResponse({
                'code': '400',
                'msg': '聊天记录不存在!'
            })
        is_read = request.data.get('is_read', tmp_record.is_read)
        is_return = request.data.get('is_return', tmp_record.is_return)
        tmp_record.is_read = is_read
        tmp_record.is_return = is_return
        tmp_record.save()
        return Response({
            'code': '200',
            'msg': '更新成功!',
            'data': {
                'id': pk,
                'is_read': is_read,
                'is_return': is_return,
                'content': tmp_record.content
            }
        })


class WordReplyMapViewSet(viewsets.ModelViewSet):
    serializer_class = WordReplyMapSerializers
    queryset = WordReplyMap.objects.all()
    authentication_classes = (CsrfExemptSessionAuthentication,)
    pagination_class = MyPageNumberPagination  # 指定该视图类的分页器

    # 列表
    @auth(True)
    def list(self, request):
        res = super().list(request)
        data = res.data
        res.data = {
            'code': '200',
            'msg': '响应成功!',
            'data': data
        }
        return res

    # 新增
    @auth(True)
    def create(self, request):

        word = request.data.get('word')
        if tmp_wr := WordReplyMap.get_by_word(word):
            return JsonResponse({
                'code': '400',
                'msg': '该词条已存在，新增失败!'
            })

        res = super().create(request)
        data = res.data
        res.data = {
            'code': '200',
            'msg': '响应成功!',
            'data': data
        }
        return res

    # 获取/查看某一个词条
    @auth(True)
    def retrieve(self, request, pk=None):
        tmp_wr = WordReplyMap.get_by_pk(pk)
        if not tmp_wr:
            return JsonResponse({
                'code': '400',
                'msg': '词条不存在!'
            })

        data = {k: getattr(tmp_wr, k)
                for k in self.serializer_class.Meta.fields}
        res = {
            'code': '200',
            'msg': '响应成功!',
            'data': data
        }
        return JsonResponse(res)

    # 更新词库
    @auth(True)
    def update(self, request, pk=None):

        # 检查词条是否存在
        tmp_wordreply = WordReplyMap.get_by_pk(pk)
        if not tmp_wordreply:
            return JsonResponse({'code': '200', 'msg': '无相关词库记录!'})

        # 仅可更新“回复”
        tmp_wordreply.reply = request.data.get('reply', tmp_wordreply.reply)
        tmp_wordreply.save()

        data = {
            'word': tmp_wordreply.word,
            'reply': tmp_wordreply.reply,
            'time': tmp_wordreply.time
        }

        return JsonResponse({'code': '200', 'msg': '更新成功!', 'data': data})

    # 删除词库
    @auth(True)
    def destroy(self, request, pk=None):
        tmp_wordreply = WordReplyMap.get_by_pk(pk)
        if not tmp_wordreply:
            return JsonResponse({
                'code': '400',
                'msg': '删除失败,未找到相关词条!'
            })
        tmp_wordreply.delete()

        return JsonResponse({
            'code': '200',
            'msg': '删除成功!'
        })


# 定时任务
sched = Scheduler()


@sched.interval_schedule(seconds=3)
def sched_task():
    while not record_queue.empty():
        tmp_record = ChatRecord.get_by_pk(record_queue.get())
        # 未撤回和未读的消息就进行自动回复
        if not tmp_record.is_return and not tmp_record.is_read:
            msg = tmp_record.content

            reply = WordReplyMap.match(msg)  # 首先搜索词库表
            reply = reply or User.auto_reply(msg)  # 如果没有就再调用自动回复接口

            # print(f'send:{msg}')
            # print(f'reply:{reply}')

            reply_record = ChatRecord.create_record(
                tmp_record.receiver, tmp_record.sender, f'[自动回复]{reply}'
            )
            # 当前消息为自动回复
            reply_record.auto_reply = True
            reply_record.save()

            # record_queue.put(reply_record.id)


sched.start()  # 启动定时器
